package com.jwm.power.util;

import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import com.jwm.power.model.common.EnumMenu;
import com.jwm.power.model.common.EnumOperate;
import com.jwm.power.model.entity.Logs;
import com.jwm.power.model.entity.Users;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Pattern;

/**
 * @Auther: chenjinbo
 * @Date: 2019/3/21 16:56
 * @Description: 基础工具类
 */
public class Ut {

    /**
     * 获取系统当前时间
     *
     * @return
     */
    public static Date getCurrentTime() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.CHINESE);
        Date currentTime = null;
        try {
            currentTime = sdf.parse(sdf.format(new Date()));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return currentTime;
    }
    //  获取系统时间
    public static String getDataNow() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        String time = "";
        try {
            time = sdf.format(new Date());
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
        return time;
    }
    //  获取系统时间
    public static Date getAddTime(Integer day) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Calendar c = Calendar.getInstance();
        c.add(Calendar.DAY_OF_MONTH, day);
        Date time = null;
        try {
            time = sdf.parse(sdf.format(c.getTime()));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return time;
    }

    /**
     * 根据格式获取系统当前时间
     *
     * @param formatStr
     * @return
     */
    public static Date getCurrentTime(String formatStr) {
        SimpleDateFormat sdf = new SimpleDateFormat(formatStr, Locale.CHINESE);
        Date currentTime = null;
        try {
            currentTime = sdf.parse(sdf.format(new Date()));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return currentTime;
    }

    /**
     * 日期转指定格式的字符串
     *
     * @param myDate 日期
     * @param format 字符串格式
     * @return
     */
    public static String formatDateToStr(Date myDate, String format) {
        SimpleDateFormat dateFormat = new SimpleDateFormat(format, Locale.CHINESE);
        return dateFormat.format(myDate);
    }

    /**
     * 指定格式字符串转日期
     *
     * @param timeStr 字符串
     * @param format  字符串格式
     * @return
     */
    public static Date formatStrToDate(String timeStr, String format) {
        Date newDate = null;
        SimpleDateFormat formatter = new SimpleDateFormat(format, Locale.CHINA);
        try {
            newDate = formatter.parse(timeStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return newDate;
    }


    /**
     * ArrayList转数值型数组
     *
     * @param list
     * @return
     */
    public static Integer[] ArrayListToIntegerArr(List list) {
        if (list == null || list.size() == 0) {
            return null;
        }
        int size = list.size();
        Integer[] ids = new Integer[size];
        for (int i = 0; i < size; i++) {
            ids[i] = (Integer) list.get(i);
        }
        return ids;
    }

    /**
     * String[] 转 Integer[]
     *
     * @param strArr
     * @return
     */
    public static Integer[] StringArrToIntegerArr(String[] strArr) {
        if (strArr == null || strArr.length == 0) {
            return null;
        }
        Integer[] intArr = new Integer[strArr.length];
        for (int i = 0; i < strArr.length; i++) {
            if (strArr[i].matches("[+-]?[1-9]+[0-9]*(\\.[0-9]+)?")) {
                intArr[i] = Integer.valueOf(strArr[i]);
            } else {
                intArr[i] = 0;
            }
        }
        return intArr;
    }

    public static String IntegerArrToString(Integer[] arr) {
        if (arr == null || arr.length == 0) {
            return null;
        }
        String str = "";
        for (int i = 0; i < arr.length; i++) {
            if (i == 0) {
                str = arr[i].toString();
            } else {
                str += "," + arr[i].toString();
            }
        }
        return str;
    }

    /**
     * String[] 转 BigDecimal[]
     *
     * @param strArr
     * @return
     */
    public static BigDecimal[] StringArrToBigDecimalArr(String[] strArr) {
        if (strArr == null || strArr.length == 0) {
            return null;
        }
        BigDecimal[] decimalArr = new BigDecimal[strArr.length];
        for (int i = 0; i < strArr.length; i++) {
            decimalArr[i] = new BigDecimal(strArr[i]);
        }
        return decimalArr;
    }

    /**
     * 获取当前年+周：yyyyww
     *
     * @return
     */
    public static String getYearWeek() {
        Calendar rightNow = Calendar.getInstance();
        rightNow.setFirstDayOfWeek(Calendar.MONDAY); //美国是以周日为每周的第一天，现把周一设成第一天
        // 获取当前年
        int year = rightNow.get(Calendar.YEAR);
        // 获取当前周，一年中的第几周
        int week = rightNow.get(Calendar.WEEK_OF_YEAR);
        String weekStr = "";
        if (week < 10) {
            weekStr = "0" + week;
        } else {
            weekStr = "" + week;
        }

        return year + weekStr;
    }

    /**
     * 返回星期几
     *
     * @param date
     * @return
     * @throws ParseException
     */
    public static int getDayofweek(Date date) throws ParseException {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int i = cal.get(Calendar.DAY_OF_WEEK);
        i = i - 1;
        if (i == 0) {
            i = 7;
        }
        return i;
    }

    /**
     * 加一天
     *
     * @param date
     * @param interval
     * @return
     */
    public static Date addDate(Date date, Integer interval) {
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(date);
        calendar.add(calendar.DATE, interval);
        return calendar.getTime();
    }

    /**
     * 获取指定日期当前周的第一天（周一）
     *
     * @param date
     * @return
     */
    public static Date getWeekFirstDay(Date date) {
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(date);
        calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
        return calendar.getTime();
    }

    /**
     * 获取指定日期当前月的第一天
     *
     * @param date
     * @return
     */
    public static Date getMonthFirstDay(Date date) {
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, 0);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        return calendar.getTime();
    }

    /**
     * 获取指定日期当前年的第一天
     *
     * @param date
     * @return
     */
    public static Date getYearFirstDay(Date date) {
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(date);
        calendar.add(Calendar.YEAR, 0);
        calendar.set(Calendar.DAY_OF_YEAR, 1);
        return calendar.getTime();
    }

    /**
     * 获取国际化信息,根据传入语言获取对应信息
     */
    public static String getMessage(String key, String language) {
        ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
        messageSource.setCacheSeconds(-1);
        messageSource.setDefaultEncoding(StandardCharsets.UTF_8.name());
        messageSource.setBasenames("/messages/messages");

        String message = "";
        try {
            Locale locale = new Locale("zh", "CN");
            if (language != null) {
                if (language.contains("zh-CN")) {
                    locale = new Locale("zh", "CN");
                } else if (language.contains("zh-TW") || language.contains("zh-HK") || language.contains("zh-MO")) {
                    locale = new Locale("zh", "TW");
                } else if (language.contains("en")) {
                    locale = new Locale("en", "US");
                }
            }
            message = messageSource.getMessage(key, new Object[]{}, locale);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return message;
    }

    /**
     * 将秒格式化为时间格式
     *
     * @param time
     * @return
     */
    public static String secToTime(int time) {
        String timeStr = null;
        int hour = 0;
        int minute = 0;
        int second = 0;
        if (time <= 0)
            return "0:00:00";
        else {
            minute = time / 60;
            if (minute < 60) {
                second = time % 60;
                timeStr = "0:" + unitFormat(minute) + ":" + unitFormat(second);
            } else {
                hour = minute / 60;
                if (hour > 99)
                    return "99:59:59";
                minute = minute % 60;
                second = time - hour * 3600 - minute * 60;
                timeStr = unitFormat(hour) + ":" + unitFormat(minute) + ":" + unitFormat(second);
            }
        }
        return timeStr;
    }

    private static String unitFormat(int i) {
        String retStr = null;
        if (i >= 0 && i < 10)
            retStr = "0" + Integer.toString(i);
        else
            retStr = "" + i;
        return retStr;
    }

    /**
     * 获取请求客户端类型：1-PC，2-APP
     *
     * @param request
     * @return
     */
    public static Integer getClienttype(HttpServletRequest request) {
        String clienttype = request.getHeader("clienttype");
        if (clienttype == null) {
            return 1;
        }
        if (clienttype.trim().equalsIgnoreCase("app")) {
            return 2;
        } else {
            return 1;
        }
    }

    /**
     * 判断字符串是否是数字
     *
     * @param str 传入的字符串
     * @return 是整数返回true, 否则返回false
     */
    public static boolean isNumeric(String str) {
        if (str.equals("")) {
            return false;
        }
        Pattern pattern = Pattern.compile("^[-\\+]?[\\d]*$"); //速度最快
//        Pattern pattern = Pattern.compile("[0-9]*");
        return pattern.matcher(str).matches();
    }

    /**
     * 精确计算：乘法
     *
     * @param v1
     * @param v2
     * @return
     */
    public static double mul(double v1, double v2) {
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.multiply(b2).doubleValue();
    }

    /**
     * 精确计算：除法
     *
     * @param v1    被除数
     * @param v2    除数
     * @param scale 精确到小数点以后几位
     * @return
     */
    public static double div(double v1, double v2, int scale) {
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
    }

    /**
     * double类型转String类型，小数点后都为0时，不显示小数部分
     *
     * @param val
     * @return
     */
    public static String DoubleToString(double val) {
        String str = String.valueOf(val);
        int index = str.indexOf(".");
        if (index > -1) {
            String decimal = str.substring(index + 1);
            if (Integer.parseInt(decimal) == 0) {
                return str.substring(0, index);
            } else {
                return str;
            }
        } else {
            return str;
        }
    }

    /**
     * 获取字符串的真实长度：1个汉字为2个字符
     *
     * @param value
     * @return
     */
    public static int String_length(String value) {
        int valueLength = 0;
        String chinese = "[\u4e00-\u9fa5]";
        for (int i = 0; i < value.length(); i++) {
            String temp = value.substring(i, i + 1);
            if (temp.matches(chinese)) {
                valueLength += 2;
            } else {
                valueLength += 1;
            }
        }
        return valueLength;
    }

    //  转Json串
    public static void toJson(HttpServletResponse response, Object obj) throws IOException {
        response.setContentType("text/json;charset=UTF-8");
        PrintWriter printWriter = response.getWriter();
        ObjectMapper objectMapper = new ObjectMapper();
        StringWriter writer = new StringWriter();
        JsonGenerator gen = null;
        try {
            gen = objectMapper.getFactory().createGenerator(writer);
        } catch (IOException e1) {
            e1.printStackTrace();
        }
        String jsonString = "";
        try {
            objectMapper.writeValue(gen, obj);
            jsonString = writer.toString();
            gen.close();
            writer.flush();
            writer.close();
        } catch (JsonGenerationException e) {
            e.printStackTrace();
            printWriter.flush();
            printWriter.close();
        } catch (JsonMappingException e) {
            e.printStackTrace();
            printWriter.flush();
            printWriter.close();
        } catch (IOException e) {
            e.printStackTrace();
            printWriter.flush();
            printWriter.close();
        }
        printWriter.write(jsonString);
        printWriter.flush();
        printWriter.close();
    }

    //  转Json串
    public static String toJson(Object obj) throws IOException {

        ObjectMapper objectMapper = new ObjectMapper();
        StringWriter writer = new StringWriter();
        JsonGenerator gen = null;
        try {
            gen = objectMapper.getFactory().createGenerator(writer);
        } catch (IOException e1) {
            e1.printStackTrace();
            throw new RuntimeException(e1);
        }
        String jsonString = "";
        try {
            objectMapper.writeValue(gen, obj);
            jsonString = writer.toString();
            gen.close();
            writer.flush();
            writer.close();
        } catch (JsonGenerationException e) {
            e.printStackTrace();
        } catch (JsonMappingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return jsonString;
    }

    //  加载Logs
    public static Logs SaveLog(String dataType, String optContent, EnumOperate enumOperate, Users users) throws IOException {

        String strContent = enumOperate != null && enumOperate.equals("DELETE") ? "名称为" : "标识为";
        String operationContent = enumOperate + "-" + strContent + optContent + "的数据";
        Logs l = new Logs();
        l.setModulename(dataType);
        l.setOperating(operationContent);
        l.setOperatingdate(getCurrentTime());
        l.setUserid(users.getUserid());
        l.setUsername(users.getName());
        return l;
    }

    //  渲染树形数据
    public static Map<String, Object> loadTreeData(Map<String, Object> objectMap, List<Map<String, Object>> searchResult, String dataCode) {
        Map<String, Object> itemMap = new HashMap<>();
        for (String mapKey : objectMap.keySet()) {
            switch (mapKey) {
                case "pname":
                    itemMap.put(mapKey, objectMap.get(mapKey) != null ? objectMap.get(mapKey) : "根级");
                    break;
                default:
                    itemMap.put(mapKey, objectMap.get(mapKey));
                    break;
            }
        }
        itemMap.put("children", loadChilds(searchResult, itemMap, dataCode));  //  加载子集
        return itemMap;
    }

    public static List<Map<String, Object>> loadChilds(List<Map<String, Object>> dataMaps, Map<String, Object> dataMap, String dataCode) {
        List<Map<String, Object>> mapList = new ArrayList<>();
        for (Map<String, Object> objectMap : dataMaps) {
            if (objectMap.get("parentcode").equals(dataMap.get(dataCode).toString())) {
                objectMap.put("children", loadChilds(dataMaps, objectMap, dataCode));  //  加载子集
                mapList.add(objectMap);
            }
        }
        return mapList;
    }

    public static void Obj(){
        try {
            // 创建一个Model对象
            Map<String, Object> map = new HashMap<>();

            // 获取对象的Class对象
            Class<?> objClass = map.getClass();

            // 通过Class对象获取属性名
            Field[] fields = objClass.getDeclaredFields();

            // 根据属性名获取属性值
            for (Field field : fields) {
                // 设置访问权限，以便获取私有属性的值
                field.setAccessible(true);
                // 获取属性名
                String fieldName = field.getName();
                // 获取属性值
                Object fieldValue = field.get(map);

                // 打印输出属性名和属性值
                System.out.println(fieldName + ": " + fieldValue);
            }
        }catch (Exception ex){

        }


    }
}
